/*
	YoghurtGum - 2D Game Engine

	Copyright 2009-2011 Quinten Lansu
	
	Licensed under the Apache License, Version 2.0 (the "License"); you may not 
	use this file except in compliance with the License. You may obtain a copy 
	of the License at 
		
		http://www.apache.org/licenses/LICENSE-2.0 
		
	Unless required by applicable law or agreed to in writing, software 
	distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
	WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
	License for the specific language governing permissions and limitations 
	under the License. 
*/

#ifndef _YGFUNCTIONS_H_
#define _YGFUNCTIONS_H_

//#include "YGPlatform.h"
#include "YGSettings.h"
#include "YGSources.h"

namespace YoghurtGum
{

#define YG_BYTES_TO_KILOBYTES(bytes)		bytes / 1024
#define YG_BYTES_TO_MEGABYTES(bytes)		bytes / 1048576
#define YG_KILOBYTES_TO_BYTES(kilobytes)	kilobytes * 1024
#define YG_MEGABYTES_TO_BYTES(megabytes)	megabytes * 1048576

#if YG_OS_TYPE == YG_OS_TYPE_ANDROID

	/*inline unsigned int YG_STRLEN(const char* a_String)
	{	
		unsigned int size;
		for (size = 0; a_String[size]; size++) { }
		return size;
	}*/

	#define YG_ZEROMEMORY(target, length)		memset((target), 0, (length))

	#define YG_SPRINTF(dst, maximum, format, ...)     sprintf(dst, format, __VA_ARGS__)

	//#define YG_STRCAT(target, str)				strcat((target), (str))
	inline int YG_TIMER()						{ return (int)clock(); }

	#define YG_ITOA(number, dst, maximum, precision) \
	{ \
		size_t max_str = (maximum); \
		sprintf((dst), "%d", (number)); \
	}

	#define YG_ITOW(number, dst, maximum, precision) \
	{ \
		char* t_dst = new char[(maximum + 1)]; \
		sprintf(t_dst, "%d", (number)); \
		size_t len = strlen(t_dst); \
		wchar_t* t_src = (wchar_t*)t_dst; \
		wchar_t* write = (wchar_t*)dst; \
		for (size_t i = 0; i < len; i++) \
		{ \
			*write++ = *t_src++; \
		} \
		*write = 0; \
		delete t_dst; \
	}

	#define YG_FTOA(number, dst, maximum, digits) \
	{ \
		sprintf(dst, "%f", number); \
	}

	// TODO: Android time function
	inline uint32 Time()
	{
		return 0;
	}

#elif YG_OS_TYPE == YG_OS_TYPE_WINDOWSMOBILE
	
	//#define YG_STRLEN(str)						strlen((str))
	//#define YG_STRCAT(target, str)				strcat((target), (str))
	#define YG_ZEROMEMORY(target, length)		ZeroMemory((target), (length))

	inline uint32 Time()
	{
		return (uint32)GetTickCount();
	}

	#define YG_ITOA(number, dst, maximum, precision)  _itoa(number, dst, precision)
	#define YG_SPRINTF(dst, maximum, format, ...)     sprintf(dst, format, __VA_ARGS__)

	//#define YG_TIMER()							GetTickCount()
	//#define YG_STRNCPY()

	//#define YG_EXPORT							__declspec(dllexport)

	#define YG_FTOA(number, dst, maximum, digits) \
	{ \
		_gcvt((double)(number), (digits), (dst)); \
	}

	#define YG_ITOW(number, dst, maximum, digits) \
	{ \
		_itow((number), (dst), digits); \
	}

#elif (YG_OS_TYPE == YG_OS_TYPE_BADA)

	inline uint32 Time()
	{
		Osp::Base::DateTime dt;
		Osp::System::SystemTime::GetCurrentTime(dt);
		return (uint32)dt.GetTime().GetMilliseconds();
	}

	#define YG_SPRINTF(dst, maximum, format, ...) \
	{ \
		size_t max_str = (maximum); \
		asnprintf(dst, &max_str, format, ##__VA_ARGS__); \
	}
	#define YG_ITOA(number, dst, maximum, precision) \
	{ \
		size_t max_str = (maximum); \
		asnprintf(dst, &max_str, "%d", number); \
	}
	#define YG_ITOW(number, dst, maximum, precision) \
	{ \
		char* t_dst = new char[(maximum + 1)]; \
		wchar_t* t_src = (wchar_t*)dst; \
		for (int i = 0; i < (maximum); i++) \
		{ \
			*t_dst++ = (char)(*t_src++ & 0xFF); \
		} \
		*t_dst = 0; \
		size_t max_str = (size_t)(maximum); \
		asnprintf((dst), &max_str, "%d", (number)); \
		delete t_dst; \
	}
	#define YG_FTOA(number, dst, maximum, precision) \
	{ \
		size_t max_str = (maximum); \
		asnprintf(dst, &max_str, "%f", number); \
	}
	#define YG_ATOF(src, dst, precision) \
	{ \
		dst = strtof(src, NULL); \
	}
	#define YG_ATOI(src, dst, precision) \
	{ \
		dst = strtol(src, NULL, 10); \
	}


#endif

#if defined(YG_SAFE)

	#define YG_STRLEN(src)                        strlen(src)
	#define YG_STRCPY(dst, maximum, src)          strcpy_s(dst, maximum, src)
	#define YG_STRNCPY(dst, maximum, src, len)    strncpy_s(dst, maximum, src, len)
	#define YG_STRCAT(dst, maximum, src)          strcat_s(dst, maximum, src)
	#define YG_STRNCAT(dst, maximum, src, len)    strncat_s(dst, maximum, src, len)
	#define YG_SSCANF(src, format, ...)           sscanf_s(src, format, __VA_ARGS__)

	#define YG_MBSTOWCS(dst, maximum, src, count) mbstowcs_s(NULL, dst, maximum, src, count)
	#define YG_WCSLEN(src)                        wcslen(src)
	#define YG_WCSCPY(dst, maximum, src)          wcscpy_s(dst, maximum, src)

#else

	#define YG_STRLEN(src)                        strlen(src)
	#define YG_STRCPY(dst, maximum, src)          strcpy(dst, src)
	#define YG_STRNCPY(dst, maximum, src, len)    strncpy(dst, src, len)
	#define YG_STRCAT(dst, maximum, src)          strcat(dst, src)
	#define YG_STRNCAT(dst, maximum, src, len)    strncat(dst, src, len)
	#define YG_SSCANF(src, format, ...)           sscanf(src, format, __VA_ARGS__)

	#define YG_MBSTOWCS(dst, maximum, src, count) mbstowcs(dst, src, count)
	#define YG_WCSLEN(src)                        wcslen(src)
	#define YG_WCSCPY(dst, maximum, src)          wcscpy(dst, src)

#endif

#define YG_TIMER() Time()

}; // namespace YoghurtGum

#endif
